﻿#region Header
// Copyright (c) 2015 OPEN TONE, Inc.
// Released under the MIT license
// http://opensource.org/licenses/mit-license.php
#endregion
using System;
using System.IO;
using DocumentFormat.OpenXml.Packaging;
using OpenXmlLib.Exception;
using CommonLib.Util;

namespace OpenXmlLib.Excel.Impl
{
	/// <summary>
	/// Excelを開き、各処理を行います。
	/// </summary>
	public class ExcelImpl : IDisposable, IExcel
	{
		// SpreadsheetDocumentドキュメント
		private SpreadsheetDocument spreadsheetDocument;

		/// <summary>
		/// 
		/// </summary>
		/// <see cref="IOpenXmlDocument.FilePath"/>
		public String FilePath { get; private set; }

		/// <summary>
		/// 
		/// </summary>
		/// <see cref="IExcel.Workbook"/>
		public IWorkbook Workbook
		{
			get
			{
				IWorkbook workbook = null;
				if (null != spreadsheetDocument)
				{
					workbook = new WorkbookImpl(spreadsheetDocument.WorkbookPart);
				}
				return workbook;
			}
		}

		/// <summary>
		/// private コンストラクタ
		/// </summary>
		private ExcelImpl()
		{
		}

		/// <summary>
		/// コンストラクタ
		/// </summary>
		/// <param name="filePath">対象のファイルパス</param>
		internal ExcelImpl(String filePath)
		{
			this.FilePath = filePath;
		}

		/// <summary>
		/// 指定したパスのExcelファイルを読み込みます。
		/// <param name="isEditable">書き込み可で開く場合はtrue</param>
		/// </summary>
		internal void Open(bool isEditable)
		{
			// ファイルのチェック
			ValidateOpenFile();
			// ファイルを開く
			try
			{
				this.spreadsheetDocument = SpreadsheetDocument.Open(FilePath, isEditable);
			}
			catch (IOException e)
			{
				throw new OpenXmlLibException(ErrorCodes.FAILED_TO_OPEN, null, e);
			}
			catch (OpenXmlPackageException e)
			{
				throw new OpenXmlLibException(ErrorCodes.INVALID_FILE_FORMAT, null, e);
			}
		}

		/// <summary>
		/// 開こうとするファイルを確認します。
		/// </summary>
		private void ValidateOpenFile()
		{
			AssertUtil.IsTrue(
				FileUtil.Exists(FilePath), new OpenXmlLibException(ErrorCodes.FILE_NOT_FOUND));
			AssertUtil.IsTrue(
				(0 < FileUtil.Length(FilePath)), new OpenXmlLibException(ErrorCodes.FILE_EMPTY));
		}

		/// <summary>
		/// SpreadsheetDocumentを閉じて破棄します。
		/// </summary>
		public void CloseSpreadsheetDocument()
		{
			if (null != this.spreadsheetDocument)
			{
				this.spreadsheetDocument.Close();
				this.spreadsheetDocument.Dispose();
			}
		}

		/// <summary>
		/// 終了処理を行います。
		/// </summary>
		public void Dispose()
		{
			CloseSpreadsheetDocument();
		}
	}
}
